from typing import Annotated, Optional

from fastapi import Query, Body
from pydantic import model_validator

from app.utils import types
from app.models.common import AppId, Pagination, CardTypeId
from app.models import responses


class AppCardTypesList(AppId, Pagination):
    """分页获取应用的卡种列表"""
    pass


AppCardTypesListParams = Annotated[AppCardTypesList, Query()]


class CreateCardType(AppId):
    name: str
    hours: int
    enabled: bool
    remark: str

    @model_validator(mode='before')
    @classmethod
    def before(cls, data):
        data = types.safe_dict(data)
        data['name'] = data.get('name', '')
        data['hours'] = types.safe_int(data.get('hours', None), -1)
        data['enabled'] = data.get('enabled', True)
        data['remark'] = data.get('remark', '')
        return data

    @model_validator(mode='after')
    def after(self):
        if not (2 <= len(self.name) <= 64):
            raise responses.FailureResponseError(-102, msg='卡种名称长度应介于 2-64 位')

        if self.hours < 0:
            raise responses.FailureResponseError(-102, msg='卡种的时长不能小于 0')

        if len(self.remark) > 512:
            raise responses.FailureResponseError(-102, msg='卡种的备注长度不能超过 512 个字符')

        return self


CreateCardTypeJson = Annotated[CreateCardType, Body()]


class UpdateCardType(CardTypeId):
    name: Optional[str]
    hours: Optional[int]
    enabled: Optional[bool]
    remark: Optional[str]

    @model_validator(mode='before')
    @classmethod
    def before(cls, data):
        data = types.safe_dict(data)
        data['name'] = data.get('name', None)
        data['hours'] = types.safe_int(data.get('hours', None), None)
        data['enabled'] = data.get('enabled', None)
        data['remark'] = data.get('remark', None)
        return data

    @model_validator(mode='after')
    def after(self):
        if self.name is not None and not (2 <= len(self.name) <= 64):
            raise responses.FailureResponseError(-102, msg='卡种名称长度应介于 2-64 位')

        if self.hours is not None and self.hours < 0:
            raise responses.FailureResponseError(-102, msg='卡种的时长不能小于 0')

        if self.remark is not None and len(self.remark) > 512:
            raise responses.FailureResponseError(-102, msg='卡种的备注长度不能超过 512 个字符')

        return self


UpdateCardTypeJson = Annotated[UpdateCardType, Body()]
